package com.cskaoyan.javase.oop3._0abstract._1basic;

/**
 * 抽象类的定义:
 *      在继承体系中，从祖先类开始，随着一个个子类的定义，子类变得越来越具体，而祖先类则更具有一般性和抽象性。在这种情况下，为了体现祖先类在设计上的抽象性，我们只将该类作为派生其他类的父类，而不能创建对象实例。这个时候，这样的类，我们称之为抽象类。
 *
 * 从以上定义中,你能得出什么结论?什么情况下应该使用抽象类呢?
 *      在继承层次中,处在顶层祖先类位置的类,往往才需要设置为抽象类
 *      也就是说,抽象类几乎等同于祖先类
 *      祖先类不一定是抽象类,但抽象类肯定是祖先类
 *
 *    从这个角度上来说,我们在开发中可能偶尔见到抽象类,但几乎很少定义抽象类,它的使用频率不高.
 *
 *
 * 对于一个抽象类来说:
 * [修饰符列表] abstract class 类名{
 *     //类体
 * }
 * 解释:
 *      1.抽象类的修饰符列表,当然是可以用访问权限修饰符,这一点和普通类是一样的
 *          final和abstract是冲突的,不能同时用于修饰类
 *
 *      2.抽象类的类名,为了表示它是一个特殊的类,我们习惯用"Base"或者"Abstract"开头
 *          比如: BaseAnimal,AbstractPerson....
 *          当然这不是强制的,只是推荐
 *
 * 下面主要研究抽象类的成员特点:
 *      1.普通成员
 *      2.静态成员
 *      和普通类一样,都能够正常定义
 *      使用的时候,静态成员可以直接类名点访问
 *      普通成员,依赖于子类继承后创建子类对象访问
 *
 *      3.抽象方法
 *      抽象类可以没有抽象方法吗?
 *      当然可以,但是定义抽象类的目的就是为了抽象方法
 *      如果一个抽象类,没有抽象方法,是没有太大意义的
 *      也就是说,抽象类就该有抽象方法.
 *
 *      抽象方法的语法:
 *      [修饰符列表] abstract 返回值类型 方法名(形参列表);
 *      抽象父类中的抽象方法起着"占位符"的作用
 *      一个普通子类继承抽象类,必须实现这个抽象方法
 *      也就是重写抽象方法的实现,就是方法重写.
 *
 *      4.构造器
 *      抽象类肯定是不能new对象的,那么它有构造器吗?
 *      有
 *      虽然自己不能用,但可以给子类,子类对象的初始化依赖于父类的构造器
 *
 *      所以,在java当中,任何类都有构造器,包括抽象类.
 *      这句话是完全正确的.
 *
 *      5.代码块
 *      既然有构造器,那就有构造代码块
 *      可以有静态声明,也可以允许静态代码块
 *
 *  以上做出总结,一句话描述抽象类的类中结构的特点:
 *  抽象类可以定义普通类能够定义的一切,还可以多定义一个抽象方法.这就是抽象类
 *  判断题:
 *  在不考虑创建对象的前提下,直接将一个类声明为抽象,会报错吗?
 *  不会报错
 *
 *  抽象类的子类可以有两种情况：
 *      1.普通类，普通类继承抽象类，必须实现所有的抽象方法。
 *      2.抽象类，抽象子类不需要实现抽象方法，抽象子类可以自由选择实现（或实现或不实现）。
 *
 * 反过来,抽象类可不可以继承普通类?
 * 当然是可以的,实际上一个抽象类如果不明确继承一个类
 * 那么它仍然隐式继承Object
 *
 * 扩展:
 *      抽象类中的成员方法/静态成员方法
 *      抽象类有抽象方法是很正常的,但实现方法的定义最好不要滥用
 *      只有当抽象类的子类都需要一个统一的实现,预先的标准时,再在抽象类中定义实现方法
 *
 * @since 11:47
 * @author wuguidong@cskaoyan.onaliyun.com
 */
// 抽象的人类
public abstract class BasePerson {
    int a;
    private int b;
    static int c = 20;
    static final int D = 30;
    public void test(){}
    public static void testStatic(){}

    {}
    static {}

    public BasePerson() {
        // super();
    }

    public BasePerson(int a, int b) {
        this.a = a;
        this.b = b;
    }

    // 定义抽象方法
    public abstract void testAbstract();
    public abstract void testAbstract2();
}

// Illegal combination of modifiers: 'final' and 'abstract'
// public final abstract class Demo {
// }
